#ifndef _SOCKADDR_H
#define _SOCKADDR_H
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h> 
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/sendfile.h>
#include <sys/epoll.h>
//创建一个socket套接字文件
int sockadd(){

    int sockfd = socket(PF_INET,SOCK_STREAM,0);  //设置套接字

    int opt=1;
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));//端口复用
    struct sockaddr_in addr;
    addr.sin_family = AF_INET; //ipv4形式
	addr.sin_port = htons(8888); //主机字节序转换成网络字节序 其实就是高位和低位的反转
	addr.sin_addr.s_addr = htonl(INADDR_ANY); //从哪个ip地址来的
	bind(sockfd,(struct sockaddr*)&addr,sizeof(struct sockaddr));

	//绑定了ip地址和套接字  那么就可以接收了
	int listen_ok=listen(sockfd,10); //开始监听是否有连接;	

    return sockfd;
}
//把fd加入epoll
void addfd(int epoll_fd,int connfd,bool one_shot){
    epoll_event ev;
    ev.data.fd=connfd;
    ev.events=EPOLLIN | EPOLLRDHUP;//监听数据写入|链接断开
    if(one_shot){
        ev.events|=EPOLLONESHOT;//防止一个socket被多个线程处理
    }
	epoll_ctl(epoll_fd,EPOLL_CTL_ADD,connfd,&ev);
    //设置文件描述符非阻塞
    int old_flag=fcntl(connfd,F_GETFL);
    int new_flag=old_flag|O_NONBLOCK;
    fcntl(connfd,F_SETFL,new_flag);

}
//fd从epollfd中删除
void removefd(int epoll_fd,int connfd){
epoll_ctl(epoll_fd,EPOLL_CTL_DEL,connfd,0);
close(connfd);
}
//修改权限,重置epolloneshot
void modfd(int epollfd,int fd,int ev){
    epoll_event event;
    event.data.fd=fd;
    event.events=ev|EPOLLONESHOT|EPOLLRDHUP;
    epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&event);
}

#endif